package com.lwl.jvm.thread;

import java.util.Vector;

/**<pre>
 *  Java 使用抢占式线程调度器,由CPU分配调度时间
 *  Java 中线程优先等级分为10个等级,10优先级最高1优先级最低
 * Java 线程状态分为5种:
 *     新建new
 *     运行Runnable:包括操作系统线程状态中的Running和Ready,
 *           此时处于此状态的线程有可能正在执行,也可能正在等待CPU为它分配执行时间
 *     无限期等待:处于这种状态的线程不会被分配CPU执行时间,他要等待被其他线程显示的唤醒
 *           以下方法会让线程陷入无限期的等待状态
 *           1.没有设置Timeout参数的Object.wait()方法;
 *           2.没有设置Timeout参数的Thread.join()方法;
 *           3.LockSupport.park()方法;
 *     限期等待:处于这种状态的线程也不会被分配CPU执行时间,不过无需等待其他线程显示的唤醒
 *          在一定时间之后他们会由系统自动唤醒,以下方法会让线程进入限期等待状态:
 *          1.Thread.sleep()方法
 *          2.设置了Timeout参数的Object.wait()方法
 *          3.设置了Timeout参数的Thread.join()方法
 *          4.LockSupport.parkNanos()方法
 *          4.LockSupport.parkUntil()方法
 *     阻塞:"阻塞状态"与"等待状态"的区别是,"阻塞状态"在等待着获取一个排他锁,这个事件将在另一个线程
 *          释放锁时发生;"等待状态"则是在等待一段时间或者唤醒动作的发生.在程序等待进入同步区域的时候
 *          线程将进入这种状态.
 *     结束
 *  将Java语言中各种共享的数据分为5中: 不可变,绝对线程安全,相对线程安全
 *          线程兼容和线程对立
 *   1.不可变对象(String)一定是线程安全的,保证对象行为不影响自己状态的途径很多,
 *   最简单的就是把对象中带有状态的变量声明为final
 *   2.绝对线程安全: 不管运行时如何,调用者都不需要任何额外的同步措施
 *   3.相对线程安全: 相对的线程安全就是我通常意义上所说的线程安全,
 *           他需要保证对这个对象单独的操作是线程安全的,我们在调用的时候不需要
 *           做额外的保障措施,但对于一些特定顺序的连续调用,可能需要在调用端使用
 *           额外的同步手段保证调用的正确性
 *   4.线程兼容: 对象本身不是线程安全的,但是可以在调用端正确的使用同步手段保证对象在
 *           并发环境中可以安全的使用.java API中大部分的类都是属于线程兼容的如:ArrayList,HashMap
 *   5.线程对立:无论调用端是否采取了同步措施,都无法在多线程环境中并发使用的代码.
 *
 * </pre>
 * 对vector线程安全测试<br>
 * Created by liwenlong on 2017/12/25 17:21 <br/>
 */
public class ThreadTest {
    private static Vector<Integer> vector = new Vector<>();

    public static void main(String[] args) {

        while(true){
            for (int i = 0; i < 10; i++) {
                vector.add(i);
            }

            Thread removeThread = new Thread(new Runnable() {
                @Override
                public void run() {
                    synchronized (vector){
                        for (int i = 0; i <vector.size() ; i++) {
                            vector.remove(i);
                        }
                    }
                }
            });

            Thread printThread = new Thread(new Runnable() {
                @Override
                public void run() {
                    synchronized (vector){
                        int size = vector.size();
                        for (int i = 0; i < size ; i++) {
                            System.out.println(vector.get(i));
                        }
                    }
                }
            });

            removeThread.start();
            printThread.start();


            while(Thread.activeCount() > 20){
            }

        }

    }




}
